"""
Authentication utilities for admin access control.

Functions:
- login_required: Decorator to protect admin routes
- get_current_admin: Get the currently logged-in administrator
- log_audit_entry: Log administrative actions to audit trail
"""
from functools import wraps
from flask import session, redirect, url_for, request
from app.models import db, Administrator, AuditLog
import json


def login_required(f):
    """
    Decorator to require admin authentication for a route.

    Usage:
        @app.route('/admin/dashboard')
        @login_required
        def dashboard():
            return render_template('admin/dashboard.html')

    If the user is not authenticated, redirects to login page with
    the original URL as a 'next' parameter.
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'admin_id' not in session:
            # Store the original URL path (not full URL) to redirect back after login
            return redirect(url_for('admin.login', next=request.path))
        return f(*args, **kwargs)
    return decorated_function


def get_current_admin():
    """
    Get the currently logged-in administrator from the session.

    Returns:
        Administrator: The current admin user object, or None if not logged in
    """
    admin_id = session.get('admin_id')
    if admin_id:
        return Administrator.query.get(admin_id)
    return None


def log_audit_entry(admin_id, action, resource_type=None, resource_id=None, details=None):
    """
    Log an administrative action to the audit trail.

    Args:
        admin_id (int): ID of the administrator performing the action
        action (str): Action type (e.g., 'login', 'create_doc', 'update_doc', 'delete_doc')
        resource_type (str, optional): Type of resource affected (e.g., 'documentation')
        resource_id (int, optional): ID of the affected resource
        details (dict or str, optional): Additional details (will be JSON-encoded if dict)

    Returns:
        AuditLog: The created audit log entry

    Example:
        log_audit_entry(
            admin_id=1,
            action='create_doc',
            resource_type='documentation',
            resource_id=5,
            details={'title': 'Getting Started', 'format': 'markdown'}
        )
    """
    # Convert dict details to JSON string
    if isinstance(details, dict):
        details = json.dumps(details)

    audit_entry = AuditLog(
        admin_id=admin_id,
        action=action,
        resource_type=resource_type,
        resource_id=resource_id,
        details=details
    )

    db.session.add(audit_entry)
    db.session.commit()

    return audit_entry


def get_request_details():
    """
    Extract request details for audit logging (IP address, user agent).

    Returns:
        dict: Dictionary with 'ip_address' and 'user_agent'
    """
    return {
        'ip_address': request.remote_addr,
        'user_agent': request.headers.get('User-Agent', 'Unknown')
    }
